package com.atguigu.tingshu.album.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.atguigu.tingshu.album.mapper.AlbumAttributeValueMapper;
import com.atguigu.tingshu.album.mapper.AlbumInfoMapper;
import com.atguigu.tingshu.album.mapper.AlbumStatMapper;
import com.atguigu.tingshu.album.mapper.TrackInfoMapper;
import com.atguigu.tingshu.album.service.AlbumInfoService;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.execption.GuiguException;
import com.atguigu.tingshu.common.result.ResultCodeEnum;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.album.AlbumAttributeValue;
import com.atguigu.tingshu.model.album.AlbumInfo;
import com.atguigu.tingshu.model.album.AlbumStat;
import com.atguigu.tingshu.query.album.AlbumInfoQuery;
import com.atguigu.tingshu.vo.album.AlbumInfoVo;
import com.atguigu.tingshu.vo.album.AlbumListVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

@Slf4j
@Service
@SuppressWarnings({"all"})
public class AlbumInfoServiceImpl extends ServiceImpl<AlbumInfoMapper, AlbumInfo> implements AlbumInfoService {

    private static final List<String> PAY_TYPE = List.of(SystemConstant.ALBUM_PAY_TYPE_REQUIRE, SystemConstant.ALBUM_PAY_TYPE_VIPFREE);

	@Autowired
	private AlbumInfoMapper albumInfoMapper;

    @Autowired
    private AlbumAttributeValueMapper albumAttributeValueMapper;

    @Autowired
    private AlbumStatMapper albumStatMapper;

    @Autowired
    private TrackInfoMapper trackInfoMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveAlbumInfo(AlbumInfoVo albumInfoVo) {
        AlbumInfo albumInfo = BeanUtil.copyProperties(albumInfoVo, AlbumInfo.class);
        albumInfo.setUserId(AuthContextHolder.getUserId());
        albumInfo.setIncludeTrackCount(0);
        // 如果是付费专辑，那么设置前五集免费试看
        if (PAY_TYPE.contains(albumInfo.getPayType())) {
            albumInfo.setTracksForFree(5);
        }
        albumInfo.setStatus(SystemConstant.ALBUM_STATUS_PASS);
        // 保存专辑信息
        albumInfoMapper.insert(albumInfo);

        // 保存专辑属性信息
        List<AlbumAttributeValue> albumAttributeValueVoList = albumInfo.getAlbumAttributeValueVoList();
        albumAttributeValueVoList.forEach(albumAttributeValue -> albumAttributeValue.setAlbumId(albumInfo.getId()));
        albumAttributeValueMapper.batchInsert(albumAttributeValueVoList);

        // 保存专辑统计信息
        addAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_PLAY);
        addAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_SUBSCRIBE);
        addAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_BUY);
        addAlbumStat(albumInfo.getId(), SystemConstant.ALBUM_STAT_COMMENT);
    }

    @Override
    public Page<AlbumListVo> findUserAlbumPage(Integer pageNo, Integer pageSize, AlbumInfoQuery albumInfoQuery) {
        Page<AlbumListVo> page = new Page<>(pageNo, pageSize);
        // 如果入参中的userId为空,那么查询当前登录用户的专辑分页信息
        if (Objects.isNull(albumInfoQuery.getUserId())) {
            albumInfoQuery.setUserId(AuthContextHolder.getUserId());
        }
        List<AlbumListVo> albumListVos = albumInfoMapper.selectUserAlbumPage(page, albumInfoQuery);
        page.setRecords(albumListVos);
        return page;
    }

    /**
     * @Description 删除规则
     * 1.首先判断专辑下是否包含声音,如果包含声音.那么不允许删除专辑
     * 2.如果没有声音,那么可以删除专辑信息
     * 3.专辑关联的属性信息也需要删除
     * 4.专辑的统计信息也需要删除
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeAlbumInfo(Long id) {
        if (Objects.isNull(id)) {
            log.warn("AlbumInfoServiceImpl removeAlbumInfo albumId isNull.");
            return;
        }

        Long currUserId = AuthContextHolder.getUserId();
        // 首先判断专辑下是否包含声音信息
        int count = trackInfoMapper.albumHasTrack(id, currUserId);
        if (count > 0) {
            throw new GuiguException(ResultCodeEnum.ALBUM_HAS_TRACK);
        }

        log.info("AlbumInfoServiceImpl removeAlbumInfo albumId is {}", id);
        // 说明:实际上第一个参数没有作用,直接传null
//        albumInfoMapper.update(albumInfo, new LambdaUpdateWrapper<AlbumInfo>().set(AlbumInfo::getIsDeleted, 1).eq(AlbumInfo::getId, id));

        // 删除专辑信息
        albumInfoMapper.update(null, new LambdaUpdateWrapper<AlbumInfo>()
                .set(AlbumInfo::getIsDeleted, 1)
                .eq(AlbumInfo::getId, id));

        // 删除专辑属性信息
        albumAttributeValueMapper.update(null, new LambdaUpdateWrapper<AlbumAttributeValue>()
                .set(AlbumAttributeValue::getIsDeleted, 1)
                .eq(AlbumAttributeValue::getAlbumId, id));

        // 删除专辑统计信息
        albumStatMapper.update(null, new LambdaUpdateWrapper<AlbumStat>()
                .set(AlbumStat::getIsDeleted, 1)
                .eq(AlbumStat::getAlbumId, id));
    }

    @Override
    public AlbumInfo getAlbumInfoById(Long id) {
        return albumInfoMapper.selectAlbumInfoById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateAlbumInfo(Long id, AlbumInfo albumInfo) {
        if (Objects.isNull(id) || Objects.isNull(albumInfo)) {
            log.warn("AlbumInfoServiceImpl updateAlbumInfo end.");
            return;
        }
        // 更新专辑信息
        albumInfo.setId(id);
        albumInfoMapper.updateById(albumInfo);

        // 更新专辑属性信息,操作逻辑:先删除对应专辑的属性信息,然后重新添加
        albumAttributeValueMapper.delete(new LambdaQueryWrapper<AlbumAttributeValue>().eq(AlbumAttributeValue::getAlbumId, id));
        albumInfo.getAlbumAttributeValueVoList().forEach(albumAttributeValue -> albumAttributeValue.setAlbumId(id));
        albumAttributeValueMapper.batchInsert(albumInfo.getAlbumAttributeValueVoList());
    }

    private void addAlbumStat(Long albumId, String statType) {
        AlbumStat albumStat = new AlbumStat();
        albumStat.setAlbumId(albumId);
        albumStat.setStatType(statType);
        // 初始化数量为0
        albumStat.setStatNum(0);
        albumStatMapper.insert(albumStat);
    }
}
